/**
 * author      : dormi330
 * date        : 2018/6/26
 * project     : mybatis
 * description : 应用层服务
 */

package com.deep.trade.application.order;

import com.deep.trade.domain.order.*;
import com.deep.trade.order.query.*;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.deep.trade.common.TradeException;
import com.deep.trade.infrastructure.utils.CommonUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrderQueryService {

    @Autowired
    private OrderQueryRepository orderQueryRepository;

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    /**
     * 用户查询 - OrderSummary 列表
     *
     * @param tenantCode
     * @param memberId
     * @return
     * @throws Exception
     */
    public PageInfo<OutDtoOrderSummary> orderSummaryOfMember(String tenantCode, String memberId, int pageNum, int pageSize) throws Exception {
        logger.info("{}, tenantCode={}, memberId={}", CommonUtils.currentClassAndMethod(), tenantCode, memberId);

        if (null == tenantCode) throw new TradeException("tenantCode cannot be null");
        if (null == memberId) throw new TradeException("memberId cannot be null");

        PageInfo<OrderSummary> orderSummaryPageInfo = orderQueryRepository.orderSummaryOfMember(tenantCode, memberId, pageNum, pageSize);

        // map eo -> dto
        List<OutDtoOrderSummary> outDtoOrderSummaryList = orderSummaryPageInfo.getList().stream().map(oneOrderSummary -> {
            OutDtoOrderSummary outDtoOrderSummary = new OutDtoOrderSummary();
            BeanUtils.copyProperties(oneOrderSummary, outDtoOrderSummary);
            return outDtoOrderSummary;
        }).collect(Collectors.toList());

        return new PageInfo<>(outDtoOrderSummaryList);
    }

    // 分页获取 某个租户对所有 订单
    public PageInfo<OutDtoTradeOrder> tradeOrderListOfTenant(String tenantCode, int pageNum, int pageSize) throws Exception {
        logger.info("{}, tenantCode={}", CommonUtils.currentClassAndMethod(), tenantCode);

        if (null == tenantCode) throw new TradeException("tenantCode cannot be null");
        PageInfo<TradeOrder> tradeOrderPageInfo = orderQueryRepository.tradeOrderOfTenant(tenantCode, pageNum, pageSize);

        // map eo -> dto
        List<OutDtoTradeOrder> outDtoTradeOrderList = tradeOrderPageInfo.getList().stream().map(tradeOrder -> {
            OutDtoTradeOrder outDtoTradeOrder = new OutDtoTradeOrder();
            BeanUtils.copyProperties(tradeOrder, outDtoTradeOrder);
            return outDtoTradeOrder;
        }).collect(Collectors.toList());

        return new PageInfo<>(outDtoTradeOrderList);

    }

    // 获取用户的订单列表 done
    public PageInfo<OutDtoTradeOrder> tradeOrderListOfMember(String tenantCode, String memberId, int pageNum, int pageSize) throws Exception {
        logger.info("{}, tenantCode={}, memberId={}", CommonUtils.currentClassAndMethod(), tenantCode, memberId);
        if (null == tenantCode) throw new TradeException("tenantCode cannot be null");
        if (null == memberId) throw new TradeException("memberId cannot be null");

        PageInfo<TradeOrder> tradeOrderPageInfo = orderQueryRepository.tradeOrderOfMember(tenantCode, memberId, pageNum, pageSize);
        // map eo -> dto
        List<OutDtoTradeOrder> outDtoTradeOrderList = tradeOrderPageInfo.getList().stream().map(tradeOrder -> {
            OutDtoTradeOrder outDtoTradeOrder = new OutDtoTradeOrder();
            BeanUtils.copyProperties(tradeOrder, outDtoTradeOrder);
            return outDtoTradeOrder;
        }).collect(Collectors.toList());

        return new PageInfo<>(outDtoTradeOrderList);
    }

    public OutDtoOrderDetail tradeOrderDetail(String tenantCode, String tradeOrderId) throws Exception {

        logger.info("{}, tenantCode={}, tradeOrderId={}", CommonUtils.currentClassAndMethod(), tenantCode, tradeOrderId);

        if (null == tenantCode) throw new TradeException("tenantCode cannot be null");
        if (null == tradeOrderId) throw new TradeException("tradeOrderId cannot be null");

        TradeOrder tradeOrder = orderQueryRepository.tradeOrderOfId(tenantCode, tradeOrderId);
        if (null == tradeOrder) throw new TradeException("tradeOrderId cannot be found");

        TradeOrderStuff stuff = allStuffOfTradeOrder(tradeOrder);

        // tradeOrder => outDtoTradeOrder
        OutDtoTradeOrder outDtoTradeOrder = new OutDtoTradeOrder();
        BeanUtils.copyProperties(tradeOrder, outDtoTradeOrder);

        // orderDelivery => outDtoOrderDelivery
        OutDtoOrderDelivery outDtoOrderDelivery = new OutDtoOrderDelivery();
        BeanUtils.copyProperties(stuff.orderDelivery, outDtoOrderDelivery);

        // orderDelivery => outDtoOrderDelivery
        OutDtoOrderPayment outDtoOrderPayment = new OutDtoOrderPayment();
        if (null != stuff.orderPayment) {
            BeanUtils.copyProperties(stuff.orderPayment, outDtoOrderPayment);
        }

        //
        List<OutDtoOrderSku> outDtoOrderSkuList = stuff.tradeOrderSkuList.stream().map(orderSku -> {
            OutDtoOrderSku outDtoOrderSku = new OutDtoOrderSku();
            BeanUtils.copyProperties(orderSku, outDtoOrderSku);
            return outDtoOrderSku;
        }).collect(Collectors.toList());

        return new OutDtoOrderDetail(outDtoOrderDelivery, outDtoOrderSkuList, outDtoTradeOrder, outDtoOrderPayment);
    }

    private TradeOrderStuff allStuffOfTradeOrder(TradeOrder tradeOrder) {
        String tenantCode = tradeOrder.getTenantCode();
        String tradeOderId = tradeOrder.getId();

        //
        OrderDelivery orderDelivery = orderQueryRepository.orderDeliveryOfTradeOrder(tenantCode, tradeOderId);
        //
        List<TradeOrderSku> tradeOrderSkuList = orderQueryRepository.orderSkuOfTradeOrder(tenantCode, tradeOderId);
        //
        OrderPayment orderPayment = orderQueryRepository.paidInoOfTradeOrder(tenantCode, tradeOderId);

        return new TradeOrderStuff(orderDelivery, orderPayment, tradeOrderSkuList);
    }

    public static class TradeOrderStuff {
        OrderDelivery orderDelivery;
        OrderPayment orderPayment;
        // OrderRefundInfo orderRefundInfo;
        List<TradeOrderSku> tradeOrderSkuList;

        public TradeOrderStuff(OrderDelivery orderDelivery, OrderPayment orderPayment, List<TradeOrderSku> tradeOrderSkuList) {
            this.orderDelivery = orderDelivery;
            this.orderPayment = orderPayment;
            this.tradeOrderSkuList = tradeOrderSkuList;
        }
    }

}
